package com.kawaiim.zhj.Operator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.kawaiim.zhj.OutCard.ComputerRemindCard;
import com.kawaiim.zhj.OutCard.PlayerRemindCard;
import com.kawaiim.zhj.entity.Card;
import com.kawaiim.zhj.entity.CardOrderMode;
import com.kawaiim.zhj.entity.Player;
import com.kawaiim.zhj.utilities.Constants;


public class PeopleOperator {
    private final LordGameMode gamemode;

    //构造操作人卡组队列的类
    public PeopleOperator(LordGameMode gamemode) {
        this.gamemode = gamemode;
    }

    //更新人当前手牌中每个牌的数量(保证原来的排序)
    private void updateCardNum(Player player) {
        //更新卡组中牌的数量（便于排序）
        updateCardNum(player.cards);

    }

    //更新卡牌队列中的牌的数量
    public static void updateCardNum(List<Card> cards) {
        //按牌的大小排序
        Collections.sort(cards, Card.CompareModeCardSize);
        //改变每个牌的数量
        for (int i = 0; i < cards.size(); i++) {
            int cardnum = 1, k = i;
            //找到相似的卡
            while (i < cards.size() - 1 && cards.get(i).cardSize == cards.get(i + 1).cardSize) {
                cardnum++;
                i++;
            }
            //给每张卡设置cardNum
            for (; k <= i; k++) {
                cards.get(k).sameCardNum = cardnum;
            }
        }
    }

    //给四个玩家发牌
    public void shuffle(Player[] people) {
        //发牌前先把牌清空
        for (Player person : people) {
            person.cards.clear();
        }
        //给玩家发牌
        gamemode.Shuffle(people);

        //更新玩家卡组中卡的属性（数目）
        for (Player person : people) {
            updateCardNum(person);
        }
    }

    //判断是否能出牌     
    public boolean canOutCard(List<Card> prevCard, List<Card> myCard) {
        //先更新sameCardNum
        updateCardNum(myCard);

        //返回能否出牌
        return gamemode.canOutCard(prevCard, myCard);
    }

    //减卡并计分，如果获胜返回true，如果没有返回false，并播放倍数翻倍和提示牌没有的音效
    public boolean outCard(Player player, List<Card> card, int[] integration) {
        //删除牌
        for (int i = 0; i < card.size(); i++) {
            for (int j = 0; j < player.cards.size(); j++) {
                if (card.get(i).cardIndex == player.cards.get(j).cardIndex) {
                    player.cards.remove(player.cards.get(j));
                    break;
                }
            }
        }
        //更新卡组数量
        updateCardNum(player);

        //玩家出牌的次数加一
        player.outCardNum++;

        //如果出的是炸弹和闪电，积分翻倍
        if (card.get(0).cardSize == card.get(card.size() - 1).cardSize && card.size() >= 3 ) {
            integration[0] *= 2;
        }
        //如果出的牌是8个连牌，积分翻三倍
        else if (card.get(0).cardSize == card.get(card.size() - 1).cardSize && card.size() == 8) {
            integration[0] *= 3;
        }

        //判断牌是否出
        if (player.cards.isEmpty()) {
            player.isWin = true;
        }
        return  player.isWin;
    }

    //玩家提示出卡（
    public List<Card> remind(Player player, List<Card> prevCard) {
        if (!player.isRemind) {
            player.htCards = prevCard;
            if (prevCard == null) {
                player.isOutByMy = true;
            } else {
                player.isOutByMy = false;
            }
        }

        //如果是别人出牌，就可以出炸弹
        if (!player.isOutByMy) {
            PlayerRemindCard.remindCard(player, player.htCards, true);
        }
        //如果是自己想怎么出怎么出
        else {
            PlayerRemindCard.remindCard(player, player.htCards, false);
            //如果没找到，递归调用，因为htCardStyle已经改变了
            if (player.htCards.isEmpty()) {
                remind(player, prevCard);
                return player.htCards;
            }
        }

        List<Card> resCards = new ArrayList<>();
        //如果能提示牌，记录有牌可出，并将其返回
        if (!player.htCards.isEmpty()) {
            player.canOutCard = true;
            resCards = player.htCards;
        }
        //如果当前不能出牌，则重新提示
        else {
            player.htCards = prevCard;
        }

        //已经提醒过了
        player.isRemind = true;
        //改回人的卡组排序
        LordGameMode.changeOrder(player.cards, player.orderMode);

        return resCards;
    }

    //机器人（托管）出卡
    public List AIOutCard(Player[] people, int whoOut, int nowPerson, List<Card> prevCard) {
        ArrayList[] TCard = new ArrayList[Constants.PLAYERS_SIZE];
        for (int j = 0; j < 4; j++) {
            TCard[j] = (ArrayList) Card.CopyListCard(people[j].cards);
        }
        List resCards = ComputerRemindCard.AIOutCard(TCard,whoOut, nowPerson, prevCard);

        //更新出牌的卡牌数量后返回
        if(resCards != null && !resCards.isEmpty() ) {
            updateCardNum(resCards);
        }
        return resCards;
    }

    //结算分数  
    public void settleScore(Player[] players, Integer integration) {
        //判断地主和农民谁获胜（false是地主赢，true是农民赢）
        boolean isFarmerWin = false;


        //找到出完牌的那个人，判断他是不是地主
        int peopleNum = players.length;
        for (Player player : players) {
            if (player.isWin) {
                isFarmerWin = !player.isRedA;
                break;
            }
        }

        //地主获胜(如果农民一张牌没出，则积分翻倍）
        if (!isFarmerWin) {
            boolean isFarmerOutCard = false;
            for (Player player : players) {
                //是农民且出过一次牌
                if (!player.isRedA && player.outCardNum > 0) {
                    isFarmerOutCard = true;
                    break;
                }
            }
            //没有一个农民出过牌，底分翻倍
            if (!isFarmerOutCard) {
                integration *= 2;
            }
        }
        //农民获胜(地主只出过一手牌或不出牌，底分翻倍)
        else {
            boolean isLandlordOutCardNumLessTwo = false;
            for (Player player : players) {
                //地主只出过一手牌或不出牌
                if (player.isRedA && player.outCardNum <= 1) {
                    isLandlordOutCardNumLessTwo = true;
                    break;
                }
            }
            //地主只出过一手牌或不出牌，底分翻倍
            if (isLandlordOutCardNumLessTwo) {
                integration *= 2;
            }
        }

        //每家结算分数
        //农民获胜，地主减分，农民加分，地主获胜则相反
        if (!isFarmerWin) {
            integration *= -1;
        }
        for (Player player : players) {
            //地主获胜
            if (player.isRedA) {
                player.integration -= 3 * integration;
            } else {
                player.integration += integration;
            }
        }
    }

    //改变牌序（按钮）（改变成相反的排序）
    public void changeOrder(Player player) {
        //将玩家当前排序模式转变（按牌大小排，按牌的数量排）
        switch (player.orderMode) {
            case CARD_NUM:
                player.orderMode = CardOrderMode.CARD_SIZE;
                break;
            case CARD_SIZE:
                player.orderMode = CardOrderMode.CARD_NUM;
                break;
        }
    }
}
